"""
@Time ： 2025/8/26 14:45
@Auth ： zh
@File ：test2.py
"""

# 获取项目所有主材的合价和

import requests
import json

# 三个API的URL
URL1 = "https://test.icii.agtsci.cn/api/cis/quota/subBill/library/listSubBill"
URL2 = "https://test.icii.agtsci.cn/api/cis/quota/subBill/library/findBySubBillId"
URL3 = "https://test.icii.agtsci.cn/api/cis/quota/collect/bill/billDetail"

# 请求头，根据实际情况可能需要调整
headers = {
    "Content-Type": "application/json",
    # 如果需要认证，可以添加Authorization等头信息
    "Authorization": "bearer eab77603-2dac-4208-8986-8fd05a8ab70b"
}


def get_api_data(url, params=None):
    """发送POST请求并返回JSON数据"""
    try:
        response = requests.post(url, headers=headers, json=params)
        response.raise_for_status()  # 检查请求是否成功
        return response.json()
    except requests.exceptions.RequestException as e:
        print(f"请求错误: {e}")
        return None
    except json.JSONDecodeError:
        print("无法解析JSON响应")
        return None


def extract_first_total_cost(node, target_code):
    """递归提取第一个匹配code的totalCost，找到后立即返回"""
    # 检查当前节点是否匹配code
    if node.get("code") == target_code:
        # 提取totalCost并转换为浮点数
        try:
            return float(node.get("totalCost", 0))
        except ValueError:
            print(f"无法转换totalCost为数字: {node.get('totalCost')}")
            return None

    # 递归遍历children（若存在）
    children = node.get("children")
    if children and isinstance(children, list):
        for child in children:
            result = extract_first_total_cost(child, target_code)
            if result is not None:  # 找到第一个匹配项后立即返回
                return result
    return None  # 未找到匹配项


def main():
    # 基础参数，pageNumber会动态调整
    base_params = {
        "name": "",
        "billName": "",
        "billDesc": "",
        "saveParam": "0",
        "orderFields": [],
        "type": "1",
        "paramJsonStr": [
            "罗定市黎少中学学生宿舍楼建设工程"
        ],
        "quotaIds": [
            "7364215106428862464"
        ],
        "pageParamJson": {
            "paramJsonStr": [
                "罗定市黎少中学学生宿舍楼建设工程"
            ],
            "quotaIds": [
                "7364215106428862464"
            ],
            "saveParam": 0
        },
        "fileKindList": [],
        "regionIdList": [],
        "projectCategoryIds": [],
        "startTime": "",
        "endTime": "",
        "pageSize": 100  # 每页数量固定
    }

    total_cost_list = []
    bill_id_counter = {}  # 记录每个billId的处理次数（用于定位children索引）
    page_number = 1  # 起始页码
    total_cycles = 0  # 总数据量
    processed_count = 0  # 已处理数据量

    # 先获取总数据量
    print("获取总数据量...")
    first_page_params = base_params.copy()
    first_page_params["pageNumber"] = 1
    response_first = get_api_data(URL1, first_page_params)

    if not response_first or response_first.get("code") != 200:
        print("获取总数据量失败")
        return

    total_cycles = int(response_first.get("data", {}).get("total", 0))
    print(f"共需处理 {total_cycles} 条数据")

    # 分页处理所有数据
    while processed_count < total_cycles:
        print(f"\n===== 处理第 {page_number} 页 =====")
        # 设置当前页参数
        current_params = base_params.copy()
        current_params["pageNumber"] = page_number

        # 1. 发送第一个请求（当前页）
        print("发送第一个请求...")
        response1 = get_api_data(URL1, current_params)

        if not response1 or response1.get("code") != 200:
            print("第一个请求失败或返回错误，跳过当前页")
            page_number += 1
            continue

        data1 = response1.get("data", {})
        list_items = data1.get("list", [])
        current_page_size = len(list_items)

        if current_page_size == 0:
            print("当前页无数据，结束处理")
            break

        # 2. 循环处理当前页的每条数据
        for item in list_items:
            processed_count += 1
            print(f"\n处理第 {processed_count}/{total_cycles} 条数据")

            # 提取billId和id
            bill_id = item.get("billId")
            item_id = item.get("id")

            if not bill_id or not item_id:
                print("缺少billId或id，跳过此条数据")
                continue

            print(f"提取到 billId: {bill_id}, id: {item_id}")

            # 计算当前billId的处理次数（从1开始）
            current_count = bill_id_counter.get(bill_id, 0) + 1
            bill_id_counter[bill_id] = current_count  # 更新计数器
            print(f"当前是billId {bill_id} 的第 {current_count} 次处理")

            # 3. 发送第二个请求
            print("发送第二个请求...")
            params2 = {"id": item_id}
            response2 = get_api_data(URL2, params2)

            if not response2 or response2.get("code") != 200:
                print("第二个请求失败或返回错误，跳过此条数据")
                continue

            data2 = response2.get("data", {})
            target_code = data2.get("code")

            if not target_code:
                print("未找到目标code，跳过此条数据")
                continue

            print(f"提取到目标code: {target_code}")

            # 4. 发送第三个请求
            print("发送第三个请求...")
            params3 = {"billId": bill_id}
            response3 = get_api_data(URL3, params3)

            if not response3 or response3.get("code") != 200:
                print("第三个请求失败或返回错误，跳过此条数据")
                continue

            data3 = response3.get("data", {})
            assemble_price_infos = data3.get("assemblePriceInfos", [])

            # 5. 处理assemblePriceInfos数据（优化后逻辑）
            current_total_cost = None
            if assemble_price_infos:  # 确保assemblePriceInfos不为空
                first_item = assemble_price_infos[0]  # 取第一个元素
                children_list = first_item.get("children", [])  # 获取第一层children列表
                print(f"第一层children总数: {len(children_list)}，当前需匹配第 {current_count} 个")

                # 步骤1：检查第一层children是否有匹配
                for child in children_list:
                    if child.get("code") == target_code:
                        try:
                            current_total_cost = float(child.get("totalCost", 0))
                            print(f"在第一层children中找到匹配code的节点，提取totalCost: {current_total_cost}")
                            total_cost_list.append(current_total_cost)  # 添加到结果列表
                            break
                        except ValueError:
                            print(f"第一层匹配节点的totalCost不是有效数字: {child.get('totalCost')}")
                            break

                # 步骤2：若第一层无匹配，根据当前处理次数定位到对应的第一层children，再检查其第二层children
                if current_total_cost is None:
                    # 检查第一层children数量是否足够
                    if len(children_list) >= current_count:
                        # 获取当前次数对应的第一层children元素（索引从0开始）
                        target_first_child = children_list[current_count - 1]
                        print(f"根据处理次数定位到第一层children第 {current_count} 个元素（code: {target_first_child.get('code')}），开始检查其第二层children")

                        # 检查该元素的第二层children
                        second_children = target_first_child.get("children", [])
                        for second_child in second_children:
                            if second_child.get("code") == target_code:
                                try:
                                    current_total_cost = float(second_child.get("totalCost", 0))
                                    print(f"在对应第一层元素的第二层children中找到匹配code的节点，提取totalCost: {current_total_cost}")
                                    total_cost_list.append(current_total_cost)  # 添加到结果列表
                                    break  # 找到后退出第二层循环
                                except ValueError:
                                    print(f"第二层匹配节点的totalCost不是有效数字: {second_child.get('totalCost')}")
                                    break
                    else:
                        print(f"第一层children数量不足（共{len(children_list)}个），无法匹配第{current_count}个元素")

                # 步骤3：若前两步无匹配，执行原过滤纯数字+按次数匹配逻辑
                if current_total_cost is None:
                    print(f"前两层均无匹配，过滤纯数字code后按处理次数查找第 {current_count} 个元素")
                    # 过滤首层children中code为纯数字的元素
                    filtered_children = []
                    for child in children_list:
                        child_code = child.get("code", "")
                        if not child_code.isdigit():  # 排除纯数字code
                            filtered_children.append(child)
                    print(f"过滤后children列表长度：{len(filtered_children)}（原长度：{len(children_list)}）")

                    if len(filtered_children) >= current_count:
                        target_child = filtered_children[current_count - 1]
                        current_total_cost = extract_first_total_cost(target_child, target_code)
                        if current_total_cost is not None:
                            total_cost_list.append(current_total_cost)  # 添加到结果列表
                            print(f"通过递归找到totalCost: {current_total_cost}")
                        else:
                            print("递归未找到有效totalCost")
                    else:
                        print(
                            f"过滤后children列表长度不足，无法获取第 {current_count} 个元素（当前长度：{len(filtered_children)}）")
            else:
                print("assemblePriceInfos列表为空，无法获取children")

        # 准备处理下一页
        page_number += 1

    # 6. 输出最终结果
    print("\n" + "=" * 50)
    print(f"处理完成，共提取 {len(total_cost_list)} 个有效totalCost值")
    print(f"totalCost列表: {total_cost_list}")
    print(f"totalCost总和: {sum(total_cost_list) if total_cost_list else 0}")  # 避免空列表sum报错


if __name__ == "__main__":
    main()